#include <stdio.h>
#include <sys/types.h>          
#include <sys/socket.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>


#define N 32

#define R 1  //register
#define L 2  //login
#define Q 3  //query
#define H 4  //history


//定义通信双方的信息结构体
typedef struct 
{
    int flag; // 1是root用户
    int type;               
    char name[N];          
    char data[256];
}MSG;


void  do_register(int sockfd, MSG *msg);
int do_login(int sockfd, MSG *msg);
void do_query(int sockfd, MSG *msg);
void do_history(int sockfd, MSG *msg);



int main(int argc, const char *argv[])
{
    int sockfd;
    struct sockaddr_in serveraddr;
    int n;
    MSG msg;

    if(argc != 3)
    {
	printf("usage:%s serverip port.\n", argv[0]);
	return -1;
    }

    if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
    {
	perror("fail to socket:");
	return -1;
    }

    bzero(&serveraddr, sizeof(serveraddr));
    serveraddr.sin_family = AF_INET;
    serveraddr.sin_addr.s_addr = inet_addr(argv[1]);
    serveraddr.sin_port = htons(atoi(argv[2]));

    if(connect(sockfd, (struct sockaddr *)&serveraddr, sizeof(serveraddr)) < 0)
    {
	perror("fail to conect:");
	return -1;
    }

    while(1)
    {
	printf("*****************************************************************\n");
	printf("* 1.register          2.login              3.quit               *\n");
	printf("*****************************************************************\n");
	printf("Please choose:");

	scanf("%d", &n);
	getchar();

	switch(n)
	{
	    case 1:
		do_register(sockfd, &msg);  //注册
		break;
	    case 2:
		if(do_login(sockfd, &msg) == 1)  //登录
		{
		    goto next;
		}
		break;
	    case 3:   //退出
		close(sockfd);  
		exit(0);
		break;
	    default:
		printf("Invalid data cmd.\n");	
	}
    }


    //用户登录成功    
next:
    while(1)
    {
	printf("*****************************************************\n");
	printf("* 1.query_word   2.history_record   3.quit          *\n");
	printf("*****************************************************\n");
	printf("Please choose:");
	scanf("%d", &n);
	getchar();

	switch(n)
	{
	    case 1:
		do_query(sockfd, &msg);  //查找单词
		break;
	    case 2:
		do_history(sockfd, &msg); //查看历史记录
		break;
	    case 3:                       //退出
		close(sockfd);
		exit(0);
		break;
	    default :
		printf("Invalid data cmd.\n");	
	}
    }    

    return 0;

}


//注册
void do_register(int sockfd, MSG *msg)
{
    msg->type = R;

    printf("Input name:");
    scanf("%s", msg->name);
    getchar();

    printf("Input passwd:");
    scanf("%s", msg->data);
    getchar();

    if(send(sockfd, msg, sizeof(MSG), 0) < 0)
    {
	printf("%s--send--%s", __func__, strerror(errno));
	return ;
    }

    if(recv(sockfd, msg, sizeof(MSG), 0) < 0)
    {
	printf("%s--recv--%s", __func__, strerror(errno));
	return;
    }

    printf("%s\n", msg->data);
}

//登录
int do_login(int sockfd, MSG *msg)
{
    msg->type = L;

    printf("Input name:");
    scanf("%s", msg->name);
    getchar();

    printf("Input passwd:");
    scanf("%s", msg->data);
    getchar();




    if(send(sockfd, msg, sizeof(MSG), 0) < 0)
    {
	printf("%s--send--%s", __func__, strerror(errno));
	return -1;
    }

    if(recv(sockfd, msg, sizeof(MSG), 0) < 0)
    {
	printf("%s--recv--%s", __func__, strerror(errno));
	return -1;
    }

    if(strncmp(msg->data, "OK", 2) == 0)
    {
	printf("Login ok!\n");
	return 1;
    }
    else
    {
	printf("%s\n", msg->data);
	return -1;
    }
}


//查询
void do_query(int sockfd, MSG *msg)
{
    msg->type = Q;
    puts("----------------");

    while(1)
    {
	printf("Input word:");
	bzero(msg->data, sizeof(msg->data));
	scanf("%s", msg->data);
	getchar();

	if(strncmp(msg->data, "#", 1) == 0)
	{
	    break;
	}

	if(send(sockfd, msg, sizeof(MSG), 0) < 0)
	{
	    printf("%s--send--%s\n", __func__, strerror(errno));
	    break;
	}

	if(recv(sockfd, msg, sizeof(MSG), 0) < 0)
	{
	    printf("%s--recv--%s\n", __func__, strerror(errno));
	    break;
	}

	printf("%s\n", msg->data);
    }

}

//历史记录
void do_history(int sockfd, MSG *msg)
{
    msg->type = H;

    if(send(sockfd, msg, sizeof(MSG), 0) < 0)
    {
	printf("%s--send--%s\n", __func__, strerror(errno));
	return;
    }

    while(1)
    {
	if(recv(sockfd, msg, sizeof(MSG), 0) < 0)
	{
	    printf("%s--recv--%s\n", __func__, strerror(errno));
	    break;
	}

	if(msg->data[0] == '\0')
	    break;

	printf("%s\n", msg->data);	
    }
}
